package com.example.werewolf.todo;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

/**
 * 游戏动作模型
 * 代表一个玩家在特定游戏阶段执行的操作。
 */
@Data
public class GameAction {

    // ========== 动作类型枚举 ==========

    /**
     * 定义游戏中所有可能的动作类型
     * 使用枚举可以提高代码的可读性和类型安全性。
     */
    public enum ActionType {
        // 夜晚行动
        KILL("刀人"),           // 狼人夜间杀人
        SAVE("救人"),           // 女巫使用解药
        POISON("毒人"),         // 女巫使用毒药
        CHECK("查验"),          // 预言家查验身份

        // 白天行动
        SPEECH("发言"),         // 玩家发言
        VOTE("投票"),           // 投票放逐玩家
        SHERIFF_VOTE("警长投票"), // 投票选警长
        NOMINATE("上警"),       // 举手上警
        DECLINE_NOMINATE("不上警"), // 不举手上警
        CHOOSE_SPEECH_ORDER("选择发言顺序"), // 警长选择发言起始点和方向

        // 通用/系统
        PASS("跳过"),           // 什么都不做（如女巫选择不用药）
        PRIVATE_MESSAGE("私信"),  // （可选）用于AI间私聊，非标准规则
        UNKNOWN("未知");        // 用于处理解析失败的情况

        private final String description;

        ActionType(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }

        /**
         * 根据字符串描述查找对应的 ActionType
         * 方便从 LLM 的 JSON 响应中解析
         */
        public static ActionType fromDescription(String desc) {
            for (ActionType type : ActionType.values()) {
                if (type.description.equals(desc)) {
                    return type;
                }
            }
            return UNKNOWN;
        }
    }

    // ========== 核心属性 ==========

    /**
     * 执行此动作的玩家ID (e.g., "1", "2", ... "8")
     */
    @JsonProperty("playerId")
    private final String playerId;

    /**
     * 动作类型 (e.g., ActionType.KILL, ActionType.SPEECH)
     */
    @JsonProperty("actionType")
    private final ActionType actionType;

    /**
     * 动作的目标玩家ID (如果适用)
     * 例如：被刀的玩家、被投的玩家、被查验的玩家。
     * 对于无目标的动作（如发言、上警），此字段为 null。
     */
    @JsonProperty("target")
    private final String target;

    /**
     * 动作的详细内容或描述
     * 主要用于“发言”动作，存储玩家的发言文本。
     * 对于其他动作，可以存储额外的描述信息（如“我选择从3号开始递减发言”）。
     */
    @JsonProperty("content")
    private final String content;

    // ========== 构造函数 ==========

    @JsonCreator
    public GameAction(
            @JsonProperty("playerId") String playerId,
            @JsonProperty("actionType") String actionTypeDesc,
            @JsonProperty("target") String target,
            @JsonProperty("content") String content) {
        this.playerId = playerId;
        this.actionType = ActionType.fromDescription(actionTypeDesc);
        this.target = target;
        this.content = content != null ? content : "";
    }

    // 提供一个更“类型安全”的构造函数，供内部代码使用
    public GameAction(String playerId, ActionType actionType, String target, String content) {
        this.playerId = playerId;
        this.actionType = actionType;
        this.target = target;
        this.content = content != null ? content : "";
    }

    // ========== Getter 方法 ==========

    public String getPlayerId() {
        return playerId;
    }

    public ActionType getActionType() {
        return actionType;
    }

    public String getTarget() {
        return target;
    }

    public String getContent() {
        return content;
    }

    // ========== 重写 toString 方法，方便调试 ==========

    @Override
    public String toString() {
        return "GameAction{" +
                "playerId='" + playerId + '\'' +
                ", actionType=" + actionType +
                ", target='" + target + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}
